package com.heima.comment.service.impl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.heima.aliyunsecurity.GreenTextScan;
import com.heima.comment.service.CommentReplyService;
import com.heima.common.exception.CustomException;
import com.heima.feigns.user.UserFeign;
import com.heima.model.comment.dtos.CommentReplyDto;
import com.heima.model.comment.dtos.CommentReplyLikeDto;
import com.heima.model.comment.dtos.CommentReplySaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentReply;
import com.heima.model.comment.pojos.ApCommentReplyLike;
import com.heima.model.comment.vos.ApCommentReplyVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.utils.threadlocal.AppThreadLocalUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author admin
 */
@Service
public class CommentReplyServiceImpl implements CommentReplyService {

    @Resource
    MongoTemplate mongoTemplate;

    @Resource
    UserFeign userFeign;

    @Resource
    private GreenTextScan greenTextScan;

    @Override
    public ResponseResult loadCommentReply(CommentReplyDto dto) {
        //1. 校验参数
        if (ObjectUtils.isEmpty(dto.getCommentId())) {
            CustomException.custom(AppHttpCodeEnum.PARAM_REQUIRE, "缺少评论ID");
        }
        if (ObjectUtils.isEmpty(dto.getMinDate())) {
            dto.setMinDate(new Date());
        }
        if (ObjectUtils.isEmpty(dto.getSize()) || dto.getSize() < 1) {
            dto.setSize(10);
        }
        //2. 根据条件：评论ID且小于回复的最小时间，按照回复时间的降序排序，并分页查询
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId())
                .and("createdTime").lt(dto.getMinDate()))
                .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                .limit(dto.getSize());
        List<ApCommentReply> apCommentReplies = mongoTemplate.find(query, ApCommentReply.class);
        //3. 判断用户是否登录,若没登录且没有回复信息
        ApUser user = AppThreadLocalUtils.getUser();
        if (ObjectUtils.isEmpty(user) || apCommentReplies.size() == 0) {
            return ResponseResult.okResult(apCommentReplies);
        }
        //3.1 查询当前登录用户对哪些回复信息点过赞
        List<String> commentReplyIdList = apCommentReplies.stream().map(ApCommentReply::getId).collect(Collectors.toList());
        Query likeQuery = Query.query(Criteria.where("commentReplyId").in(commentReplyIdList).and("authorId").is(user.getId()));
        List<ApCommentReplyLike> apCommentReplyLikes = mongoTemplate.find(likeQuery, ApCommentReplyLike.class);
        //如果没有点过赞直接返回
        if (apCommentReplyLikes.size() == 0) {
            return ResponseResult.okResult(apCommentReplies);
        }
        //点过赞的回复ID集合
        List<String> likedReplyIdList = apCommentReplyLikes.stream().map(ApCommentReplyLike::getCommentRepayId).collect(Collectors.toList());
        List<ApCommentReplyVo> replyVoList = apCommentReplies.stream().map(apCommentReply -> {
            ApCommentReplyVo apCommentReplyVo = new ApCommentReplyVo();
            BeanUtils.copyProperties(apCommentReply, apCommentReplyVo);
            if (likedReplyIdList.contains(apCommentReplyVo.getId())) {
                apCommentReplyVo.setOperation((short) 0);
            }
            return apCommentReplyVo;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(replyVoList);
    }

    @Override
    public ResponseResult saveCommentReply(CommentReplySaveDto dto) {
        //1. 校验参数：评论id、评论内容、登录状态
        if (ObjectUtils.isEmpty(dto.getCommentId())) {
            CustomException.custom(AppHttpCodeEnum.PARAM_REQUIRE, "缺少评论ID");
        }
        if (StringUtils.isBlank(dto.getContent()) || dto.getContent().length() > 140) {
            CustomException.custom(AppHttpCodeEnum.PARAM_INVALID, "评论内容为空或字数超出限制");
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if (ObjectUtils.isEmpty(user)) {
            CustomException.custom(AppHttpCodeEnum.NEED_LOGIN, "需要登录");
        }
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (ObjectUtils.isEmpty(apComment)) {
            CustomException.custom(AppHttpCodeEnum.DATA_NOT_EXIST, "该评论信息不存在");
        }
        //2. 根据登录用户ID查询登录用户信息
        user = userFeign.findUserById(Long.valueOf(user.getId()));
        if (ObjectUtils.isEmpty(user)) {
            CustomException.custom(AppHttpCodeEnum.DATA_NOT_EXIST, "登录用户信息不存在");
        }
        //3. 检验文本安全
        Map map = null;
        try {
            map = greenTextScan.greenTextScan(dto.getContent());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //4. 保存评论回复内容
        String suggestion = (String) map.get("suggestion");
        if ("pass".equals(suggestion)) {
            ApCommentReply apCommentReply = new ApCommentReply();
            apCommentReply.setAuthorId(user.getId());
            apCommentReply.setAuthorName(user.getName());
            apCommentReply.setCommentId(dto.getCommentId());
            apCommentReply.setContent(dto.getContent());
            apCommentReply.setLikes(0);
            apCommentReply.setCreatedTime(new Date());
            apCommentReply.setUpdatedTime(new Date());
            mongoTemplate.save(apCommentReply);
            //5. 更新评论回复数量
            apComment.setReply(apComment.getReply() + 1);
            mongoTemplate.save(apComment);
            return ResponseResult.okResult();
        } else {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_ERROR, "评论内容违规");
        }
    }

    @Override
    public ResponseResult saveCommentReplyLike(CommentReplyLikeDto dto) {
        // 1. 校验参数：评论回复ID，点赞方式0/1，登录状态
        if (ObjectUtils.isEmpty(dto) || ObjectUtils.isEmpty(dto.getOperation())) {
            CustomException.custom(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getOperation() != 0 && dto.getOperation() != 1) {
            CustomException.custom(AppHttpCodeEnum.PARAM_INVALID, "点赞方式参数错误");
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if (ObjectUtils.isEmpty(user)) {
            CustomException.custom(AppHttpCodeEnum.NEED_LOGIN, "请先登录");
        }
        // 2. 根据回复ID 查询回复
        ApCommentReply commentReply = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentReply.class);
        if (ObjectUtils.isEmpty(commentReply)) {
            CustomException.custom(AppHttpCodeEnum.DATA_NOT_EXIST, "该回复信息不存在");
        }
        Query query = Query.query(
                Criteria.where("commentReplyId").is(dto.getCommentRepayId())
                        .and("authorId").is(user.getId())
        );
        ApCommentReplyLike commentReplyLike = mongoTemplate.findOne(query, ApCommentReplyLike.class);
        // 用户不能重复点赞
        if (!ObjectUtils.isEmpty(commentReplyLike) && dto.getOperation() == 0 && commentReplyLike.getOperation() == 0) {
            CustomException.custom(AppHttpCodeEnum.DATA_EXIST, "请勿重复点赞");
        }
        // 3. 保存点赞数据
        if (dto.getOperation() == 0) {
            // 点赞数+1 保存评论信息
            commentReply.setLikes(commentReply.getLikes() + 1);
            mongoTemplate.save(commentReply);

            // 保存点赞信息
            commentReplyLike = new ApCommentReplyLike();
            commentReplyLike.setAuthorId(user.getId());
            commentReplyLike.setCommentRepayId(dto.getCommentRepayId());
            commentReplyLike.setOperation(dto.getOperation());
            mongoTemplate.save(commentReplyLike);
        } else {
            //取消点赞
            commentReply.setLikes(
                    commentReply.getLikes() <= 0 ? 0 : commentReply.getLikes() - 1);
            mongoTemplate.save(commentReply);
            //删除点赞信息
            mongoTemplate.remove(query, ApCommentReplyLike.class);
        }
        //4. 返回点赞数量
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes", commentReply.getLikes());
        return ResponseResult.okResult(resultMap);
    }
}
